'''
Created on 10.03.2012

@author: myaut
'''

from salsa.util.io import IOFeederReply

from salsa.service import Service
from salsa.util import LoggerSeverity
from salsa.util.rpc import RPCError, RPCInfo, RPCProtocol

import sqlite3

macros_db_create = ['''
    create table if not exists macroses (
        id integer primary key autoincrement,
        
        name text,
        args text,
        body text,
        
        src_name text,
        src_line integer
    );
''']

class MacrosDB(Service):
    def __init__(self):
        Service.__init__(self)
        
        self.db_path = self.core.abs_data_path(self.params.get('macrosdb_path', 'macrosdb.sqldb'))
        self.db_connect()
        
        self.blacklist = []
        bl_path = self.params.get('blacklist', None)
        if bl_path:
            self.create_blacklist(self.core.abs_data_path(bl_path))
    
    def create_blacklist(self, bl_path):
        bl_file = file(bl_path, 'r')
        
        for macros in bl_file:
            self.blacklist.append(macros)
    
    def db_connect(self):
        self.db_conn = sqlite3.connect(self.db_path, check_same_thread = False)
            
        for db_create_expr in macros_db_create:
            self.db_conn.execute(db_create_expr)
        self.db_conn.commit()
        
        self.db_conn.text_factory = str
        
        self.logger.log(LoggerSeverity.LS_INFO, 'Source tree is connected to %s' % self.db_path)
    
    def add_macros(self, name, args, body, coord):
        if name in self.blacklist: 
            self.logger.log(LoggerSeverity.LS_NOTICE, 'Ignored macros %s (blacklist)' % name)
            
            return RPCProtocol.STATUS_OK
        
        self.logger.log(LoggerSeverity.LS_NOTICE, 'Added macros %s' % name)
        
        self.db_conn.execute('INSERT INTO macroses VALUES (NULL, ?, ?, ?, ?, ?)',
                                (name, args, body, coord[0], coord[1]));
        self.db_conn.commit()
        
        return RPCProtocol.STATUS_OK
    
    def list_macroses(self):
        cursor = self.db_conn.execute('SELECT * FROM macroses')
        
        return IOFeederReply(iter(cursor.fetchall()))

    def _macros_info(self, name):
        cursor = self.db_conn.execute('SELECT id FROM macroses WHERE name = ?', (name, ))
        
        return cursor.fetchone()

    def macros_exists(self, name):
        return bool(self._macros_info(name))
    
    def macros_info(self, name):
        return IOFeederReply(iter(self._macros_info(name)))
    
    def delete_macros(self, name):
        self.db_conn.execute('DELETE FROM macroses WHERE name = ?', (name, ))
        self.db_conn.commit()
        
        return RPCProtocol.STATUS_OK
    
    def delete_source(self, src_name):
        # delete all references to source
        self.db_conn.execute('DELETE FROM macroses WHERE src_name = ?', (src_name, ))
        self.db_conn.commit()
        
        return RPCProtocol.STATUS_OK
    
    def do_stop(self):
        self.db_conn.close()

MacrosDB.rpc_info = RPCInfo()
MacrosDB.rpc_info.register(MacrosDB, 'add_macros', 'list_macroses', 'macros_info', 
                           'macros_exists', 'delete_macros', 'delete_source')